package com.example.pcbackend.controller;

import com.auth0.jwt.algorithms.Algorithm;
import com.example.pcbackend.config.UserContext;
import com.example.pcbackend.enums.QrCodeStatusEnum;
import com.example.pcbackend.globa.GlobalException;
import com.example.pcbackend.pojo.LoginTicket;
import com.example.pcbackend.pojo.SysUser;
import com.example.pcbackend.service.RedisService;
import com.example.pcbackend.utils.JwtUtil;
import com.example.pcbackend.utils.qrcode.QRCodeUtil;
import com.example.pcbackend.vo.ResultJson;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

/***
 * @title IndexController
 * @description <description class purpose>
 * @author WeiShuo
 * @version 1.0.0
 * @create 2023/10/4 19:38
 **/
@Slf4j
@Validated
@RequestMapping("/index")
@Controller
public class IndexController {

    @Autowired
    private RedisService redisService;


    /**
     * 生成app登录二维码流
     *
     */
    @ResponseBody
    @RequestMapping(value = "/scanQrcodeLogin/qrcode", method = RequestMethod.GET)
    public ResultJson generateQrcode() {

        String uuid = UUID.randomUUID().toString();
        LoginTicket loginTicket = new LoginTicket();
        // 二维码最初为 WAITING 状态
        loginTicket.setStatusCode(QrCodeStatusEnum.WAITING.getStatusCode());
        loginTicket.setUuid(uuid);
        //存入 redis 过期时间5分钟
//        redisUtils.set(uuid, loginTicket, UUID_EXPIRE_TIME);
        redisService.set(uuid, loginTicket, 5 * 60L);

        //二维码内容
        Map<Object, Object> values = new HashMap<>();
        values.put("token", uuid);

        ByteArrayOutputStream outputStream = null;
        try {

            ObjectMapper objectMapper = new ObjectMapper();
            String jsonVal = objectMapper.writeValueAsString(values);

            //获取二维码的图片数据流
            BufferedImage bufferedImage = QRCodeUtil.encode(jsonVal,
                    null, false);

            outputStream = new ByteArrayOutputStream();
            //将图片输出到页面展示
            ImageIO.write(bufferedImage, "jpg", outputStream);

            String qrcodeBytes = Base64.getEncoder().encodeToString(outputStream.toByteArray());
            Map<Object, Object> resultMap = new HashMap<>();
            resultMap.put("token", uuid);
            resultMap.put("qrcodeBytes", qrcodeBytes);

            return  ResultJson.success(resultMap,"操作成功");
        } catch (Exception e) {
            log.error("二维码创建失败！", e);
        }finally {

            try {
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return null;

    }



    /**
     * 获取二维码状态
     * @param token 临时二维码登录凭证
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/scanQrcodeLogin/getQrCodeStatus", method = RequestMethod.GET)
    public ResultJson<Map<Object, Object>> getQrCodeStatus(@RequestParam String token,
                                      HttpServletRequest request, HttpServletResponse response) {
        Map<Object, Object> resultMap = new HashMap<>();

        Object o = redisService.get(token);
        if (o == null) {
            throw new GlobalException("二维码无效");
        }
        LoginTicket loginTicket = (LoginTicket) o;

        Integer statusCode = loginTicket.getStatusCode();
        //User user = userService.selectByUserId(loginTicket.getUserId());

        String username = loginTicket.getUsername();
        SysUser user = new SysUser(username, null);

        resultMap.put("statusCode", statusCode);
        //二维码状态为已取消
        if ((statusCode).equals(QrCodeStatusEnum.CANCEL.getStatusCode())) {
            //redisService.remove(token);

        }

        //二维码状态为已确定 用户确认后为 PC 端生成 access_token
        if ((statusCode).equals(QrCodeStatusEnum.CONFIRMED.getStatusCode())) {

            /*Map<String, String> parameters=new HashMap<>();
            parameters.put("client_id","android");
            parameters.put("grant_type","password");
            parameters.put("password",user.getPassword());
            if (user.getIsEnterprise() != null && user.getIsEnterprise()==1) {
                //企业主用户
                parameters.put("userType","enterprise");
            }else if (user.getIsEnterprise() != null && user.getIsEnterprise()==0){
                //普通用户
                parameters.put("userType","user");
            }
            parameters.put("username",user.getUsername());
            parameters.put("client_id","android");
            //调用登录接口生成access_token
            CommonResult<?> loginResult = usersController.login(request, response, parameters);
            if (loginResult != null && loginResult.getCode()==0) {
                //获取access_token成功
                DefaultOAuth2AccessToken data = (DefaultOAuth2AccessToken) loginResult.getData();
                resultMap.put("access_token",data.getValue());
                resultMap.put("token_type",data.getTokenType());
                resultMap.put("refresh_token",data.getRefreshToken());
                resultMap.put("expires_in",data.getExpiresIn());
                resultMap.put("scope",data.getScope());
                resultMap.put("username",data.getAdditionalInformation().get("username"));
                resultMap.put("statusCode", statusCode);
            }else {
                //获取access_token失败
                throw  new RuntimeException("获取accessToken失败");
            }*/


            resultMap.put("userInfo", user);
            resultMap.put("accessToken",  createToken(user));
        }

        return ResultJson.success( resultMap, "成功");
    }


    @ResponseBody
    @RequestMapping(value = "/userInfo", method = RequestMethod.GET)
    public ResultJson getUserInfo(){
        return ResultJson.success(UserContext.getUser(),"成功");
    }

    /**
     * 创建token
     * @param user
     * @return
     */
    private String createToken(SysUser user) {

        Algorithm algorithm = JwtUtil.hs256(null);
        Date nowTime = Calendar.getInstance().getTime();
        //失效日期
        Calendar calendar = Calendar.getInstance();
//        calendar.add(Calendar.MINUTE, 10);
        calendar.add(Calendar.DATE, 7);
        Date expTime = calendar.getTime();

        HashMap<String, String> claimMap = new HashMap<>();
        claimMap.put("username", user.getUsername());
        claimMap.put("type", "pc");


        return JwtUtil.createToken("client", algorithm, nowTime, expTime, user.getUsername(), UUID.randomUUID().toString(), claimMap);
    }

}
